package org.dromara.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.demo.domain.TestDemo;
import org.dromara.demo.domain.bo.TestDemoBo;
import org.dromara.demo.domain.vo.TestDemoVo;
import org.dromara.demo.mapper.TestDemoMapper;
import org.dromara.demo.service.ITestDemoService;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：测试单表Service业务层处理
 */
@RequiredArgsConstructor
@Service
public class TestDemoServiceImpl implements ITestDemoService {

    /**
     * 测试单表Mapper接口
     */
    private final TestDemoMapper baseMapper;

    /**
     * 查询单个
     *
     * @param id 需要查询的记录的唯一标识符
     * @return 返回查询到的TestDemoVo对象，如果未找到则返回null
     */
    @Override
    public TestDemoVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询列表
     *
     * @param bo TestDemoBo对象，包含查询条件
     * @param pageQuery 分页查询对象，包含分页参数
     * @return 返回TableDataInfo<TestDemoVo>对象，其中包含分页后的测试演示数据
     */
    @Override
    public TableDataInfo<TestDemoVo> queryPageList(TestDemoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
        Page<TestDemoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 自定义分页查询
     *
     * @param bo 查询条件对象，用于指定查询的条件和筛选信息
     * @param pageQuery 分页查询对象，用于指定分页的页码和每页大小
     * @return 返回一个包含分页数据信息的对象，其中包括总记录数、当前页码、每页大小和数据列表
     */
    @Override
    public TableDataInfo<TestDemoVo> customPageList(TestDemoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TestDemo> lqw = buildQueryWrapper(bo);
        Page<TestDemoVo> result = baseMapper.customPageList(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询列表
     * @param bo 查询条件对象，包含查询测试数据所需的参数
     * @return 返回一个包含TestDemoVo对象的列表，这些对象是根据传入的查询条件从数据库中检索到的测试数据
     */
    @Override
    public List<TestDemoVo> queryList(TestDemoBo bo) {
        return baseMapper.selectVoList(buildQueryWrapper(bo));
    }

    /**
     * 构建查询包装器
     * 该方法根据TestDemoBo对象的属性值设置查询条件，用于后续的数据查询操作
     * 主要用于简化查询逻辑，集中管理查询条件，提高代码的可读性和维护性
     *
     * @param bo TestDemoBo对象，包含查询条件和参数
     * @return LambdaQueryWrapper<TestDemo>对象，包含构建的查询条件
     */
    private LambdaQueryWrapper<TestDemo> buildQueryWrapper(TestDemoBo bo) {
        // 获取参数map，用于查询条件的灵活构建
        Map<String, Object> params = bo.getParams();
        // 初始化LambdaQueryWrapper对象，用于构建查询条件
        LambdaQueryWrapper<TestDemo> lqw = Wrappers.lambdaQuery();
        // 如果testKey不为空，设置模糊查询条件
        lqw.like(StringUtils.isNotBlank(bo.getTestKey()), TestDemo::getTestKey, bo.getTestKey());
        // 如果value不为空，设置精确查询条件
        lqw.eq(StringUtils.isNotBlank(bo.getValue()), TestDemo::getValue, bo.getValue());
        // 如果开始时间和结束时间都不为空，设置时间范围查询条件
        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
            TestDemo::getCreateTime, params.get("beginCreateTime"), params.get("endCreateTime"));
        // 设置id升序排序条件，确保查询结果的顺序
        lqw.orderByAsc(TestDemo::getId);
        // 返回构建好的查询条件对象
        return lqw;
    }

    /**
     * 根据新增业务对象插入测试单表
     *
     * @param bo 测试单表新增业务对象
     * @return 插入操作的成败布尔值
     */
    @Override
    public Boolean insertByBo(TestDemoBo bo) {
        TestDemo add = MapstructUtils.convert(bo, TestDemo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 根据编辑业务对象修改测试单表
     *
     * @param bo 测试单表编辑业务对象
     * @return 如果更新成功，返回 true；否则返回 false
     */
    @Override
    public Boolean updateByBo(TestDemoBo bo) {
        TestDemo update = MapstructUtils.convert(bo, TestDemo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(TestDemo entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并删除数据
     *
     * @param ids     主键集合
     * @param isValid 是否校验,true-删除前校验,false-不校验
     * @return 返回值表示删除操作是否成功. true表示成功，false表示失败.
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 批量保存
     *
     * @param list 包含多个TestDemo对象的列表，每个对象代表一条需要保存的数据记录
     * @return 如果所有数据记录都成功保存，则返回true；否则返回false
     */
    @Override
    public Boolean saveBatch(List<TestDemo> list) {
        return baseMapper.insertBatch(list);
    }
}
